#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QObject>
#include <QHostAddress>
#include <QVariant>
#include <QFile>
#include <QMouseEvent>
#include <QBuffer>
#include <QPainter>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    sizeOfData = 0;
    firstPacket = true;
    //on start we hide screenLabel so that we have access to buttons
    ui->label->hide();
}

MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::on_pushButton_clicked()
{
    firstRun = true;
    //hide buttons and labels and show screenLabel
    ui->pushButton->hide();
    ui->lineEdit->hide();
    ui->label_2->hide();
    ui->lineEdit_2->hide();
    ui->label_3->hide();
    ui->comboBox->hide();
    ui->label_5->hide();
    ui->label->show();
    //get port and ip address and connect to server
    QString SPort = ui->lineEdit_2->text();
    port=SPort.toInt();

    ip = ui->lineEdit->text();
    if(ip[0]>64)    //if there is not a numerical ip, but domain
        ip = QHostAddress(QHostAddress::LocalHost).toString();

    quality = ui->comboBox->currentIndex();
    tcpSocket.connectToHost(ip, port);
    connect(&tcpSocket, SIGNAL(readyRead()), this, SLOT(readFromServer()));
}

void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}


void MainWindow::readFromServer(){
    // in first run signal what kind of bitmap must capture
    if(firstRun){
        firstRun=false;
        QByteArray block1;
        QDataStream out1(&block1, QIODevice::WriteOnly);
        out1 << (quint8)8; // tell server what kind of packet he is receiving (8 == type of bitmap)
        out1 << (quint8)quality;
        tcpSocket.write(block1);
        tcpSocket.flush();
        qualityTemp = quality;  //for first packet there is always quality 0, for further patket is selected
        quality=0;
    }

    if(sizeOfData == 0){
        if(tcpSocket.bytesAvailable() < (sizeof(quint32)+2*sizeof(quint16)))
            return;
        QDataStream in(&tcpSocket);
        in >> sizeOfData;
        in >> pos_x;
        in >> pos_y;
    }
    if(tcpSocket.bytesAvailable() < sizeOfData+4)
        return;
    QByteArray dataRead;
    dataRead = tcpSocket.readAll();

    // signal that packet is recived
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out << (quint8)7; // tell server what kind of packet he is receiving (7 == client recived packet)

    // send packet to server
    tcpSocket.write(block);
    tcpSocket.flush();

    sizeOfData = 0;

    dataRead = dataRead.right(dataRead.size()-4);
    //dataRead = qUncompress(dataRead); //unzip
    QPixmap pm;
    QImage img;

    switch(quality){
        case 0:img.loadFromData(dataRead, "PNG");break;
        case 1:img.loadFromData(dataRead, "JPG");break;
    }
    pm = QPixmap::fromImage(img);

    // if first packet, get server screen resolution and save it
    if(firstPacket){
        pixmap = pm;
        serverResX = pm.width();
        serverResY = pm.height();
        firstPacket = false;
        quality = qualityTemp;  //change quality to selected
    }
    else{
        QPainter painter(&pixmap);
        painter.drawPixmap(pos_x, pos_y, pm);
        painter.end();
    }

    ui->label->setPixmap(pixmap);
    ui->label->setScaledContents(true);

    //change picture size if we resize window
    int height = ui->centralWidget->height();
    int width = ui->centralWidget->width();
    ui->label->setFixedHeight(height);
    ui->label->setFixedWidth(width);

    readFromServer();
}

// we capture left/right mouse press event and save position in varible lastClick
void MainWindow::mousePressEvent(QMouseEvent *event){
    if(event->button() == Qt::LeftButton){
        lastClick = event->pos();

        // compose data to send to server
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
        out << (quint8)0; // tell server what kind of packet he is receiving (0 == left mouse press event)
        out << (quint16)(lastClick.x()*((double)serverResX/ui->label->width())); // X position of mouse press
        out << (quint16)(lastClick.y()*((double)serverResY/ui->label->height())); // Y position of mouse press
        qDebug() << "Left mouse press: " << (quint16)(lastClick.x()*((double)serverResX/ui->label->width())) << "," << (quint16)(lastClick.y()*((double)serverResY/ui->label->height()));

        // send packet to server
        tcpSocket.write(block);
        tcpSocket.flush();
    }
    else if(event->button() == Qt::RightButton){
        lastClick = event->pos();

        // compose data to send to server
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
        out << (quint8)1; // tell server what kind of packet he is receiving (1 == right mouse press event)
        out << (quint16)(lastClick.x()*((double)serverResX/ui->label->width())); // X position of mouse press
        out << (quint16)(lastClick.y()*((double)serverResY/ui->label->height())); // Y position of mouse press
        qDebug() << "Right mouse press: " << (quint16)(lastClick.x()*((double)serverResX/ui->label->width())) << "," << (quint16)(lastClick.y()*((double)serverResY/ui->label->height()));

        // send packet to server
        tcpSocket.write(block);
        tcpSocket.flush();
    }
}

void MainWindow::mouseReleaseEvent(QMouseEvent *event){
    if(event->button() == Qt::LeftButton){
        lastClick = event->pos();

        // compose data to send to server
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
        out << (quint8)2; // tell server what kind of packet he is receiving (2 == left mouse release event)
        out << (quint16)(lastClick.x()*((double)serverResX/ui->label->width())); // X position of mouse release
        out << (quint16)(lastClick.y()*((double)serverResY/ui->label->height())); // Y position of mouse release
        qDebug() << "Left mouse release: " << (quint16)(lastClick.x()*((double)serverResX/ui->label->width())) << "," << (quint16)(lastClick.y()*((double)serverResY/ui->label->height()));

        // send packet to server
        tcpSocket.write(block);
        tcpSocket.flush();
    }
    else if(event->button() == Qt::RightButton){
        lastClick = event->pos();

        // compose data to send to server
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
        out << (quint8)3; // tell server what kind of packet he is receiving (3 == right mouse release event)
        out << (quint16)(lastClick.x()*((double)serverResX/ui->label->width())); // X position of mouse release
        out << (quint16)(lastClick.y()*((double)serverResY/ui->label->height())); // Y position of mouse release
        qDebug() << "Right mouse release: " << (quint16)(lastClick.x()*((double)serverResX/ui->label->width())) << "," << (quint16)(lastClick.y()*((double)serverResY/ui->label->height()));

        // send packet to server
        tcpSocket.write(block);
        tcpSocket.flush();
    }
}

void MainWindow::mouseMoveEvent(QMouseEvent *event){
    lastClick = event->pos();

    // compose data to send to server
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out << (quint8)4; // tell server what kind of packet he is receiving (4 == mouse move event)
    out << (quint16)(lastClick.x()*((double)serverResX/ui->label->width())); // X position of mouse move
    out << (quint16)(lastClick.y()*((double)serverResY/ui->label->height())); // Y position of mouse move

    // send packet to server
    tcpSocket.write(block);
    tcpSocket.flush();
}

void MainWindow::keyPressEvent(QKeyEvent *event){
    // compose data to send to server
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out << (quint8)5; // tell server what kind of packet he is receiving (5 == keybord key press)
    out << (quint16)event->nativeScanCode(); // code of keybord key whick was pressed
    qDebug() << "Key press: " << (quint16)event->nativeScanCode();

    // send packet to server
    tcpSocket.write(block);
    tcpSocket.flush();
}

void MainWindow::keyReleaseEvent(QKeyEvent *event){
    // compose data to send to server
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out << (quint8)6; // tell server what kind of packet he is receiving (5 == keybord key release)
    out << (quint16)event->nativeScanCode(); // code of keybord key whick was released
    qDebug() << "Key release: " << (quint16)event->nativeScanCode();

    // send packet to server
    tcpSocket.write(block);
    tcpSocket.flush();
}
